﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;

namespace PhysicsSimulator
{
    public enum TurnableObjectState
    {
        IDLE,
        DRAG,
        ROLLING
    }
    class CTurnableObject : CGameObject
    {
        SpriteFont _fontArial = null;

        Vector2 _idlePosition = Vector2.Zero;
        Vector2 _position = Vector2.Zero;

        int _touchID = -1;

        TurnableObjectState _currentState = TurnableObjectState.IDLE;
        public TurnableObjectState CurrentState
        {
            get
            {
                return _currentState;
            }
            set
            {
                _currentState = value;
            }
        }

        public Vector2 Position
        {
            get
            {
                return _position;
            }
            set
            {
                if (_currentState != TurnableObjectState.IDLE)
                {
                    _position.X = value.X;
                    _position.Y = value.Y;
                }
            }
        }

        public Vector2 IdlePosition
        {
            get
            {
                return _idlePosition;
            }
            set
            {
                _idlePosition = value;
                if (_currentState == TurnableObjectState.IDLE)
                    _position = value;
            }
        }

        CSprite _objectSprite = null;

        float _weight = 0.0f;
        public float Weight
        {
            get
            {
                return _weight;
            }
        }

        CVectorForce _v = null;
        CVectorForce _aht = null;

        float _angleVeclocity = 0;

        public CTurnableObject(SpriteBatch spriteBatch, float weight, CSprite objectSprite)
            : base(spriteBatch)
        {
            _weight = weight;
            _objectSprite = objectSprite;
        }

        public override void Init(ContentManager contentManager)
        {
            _fontArial = contentManager.Load<SpriteFont>("Fonts/Arial");
            _v = new CVectorForce(SpriteBatch);
            _v.Init(contentManager);
            _v.Create(_position, Vector2.Zero, 2, Color.Green);
            _aht = new CVectorForce(SpriteBatch);
            _aht.Init(contentManager);
            _aht.Create(_position, Vector2.Zero, 2, Color.HotPink);

            base.Init(contentManager);
        }

        public override void Update(GameTimerEventArgs timer)
        {            
            base.Update(timer);
        }

        public void UpdateForceVector(float angleV, Vector2 center)
        {
            _v.Position = _position;
            _aht.Position = _position;

            Vector2 RO = Vector2.Subtract(center, _position);
            float R = RO.Length();

            Vector2 uRO;
            Vector2.Normalize(ref RO, out uRO);
            Vector2 nRO = new Vector2(uRO.Y, -uRO.X);

            _angleVeclocity = angleV;            

            _aht.VectorForce = uRO*angleV*angleV*R*0.1f;
            _v.VectorForce = nRO * angleV* R*0.1f;
        }        

        public override void Draw(GameTimerEventArgs timer)
        {
            SpriteBatch.Draw(_objectSprite.Texture, _position, null, Color.White, 0, _objectSprite.Origin, _objectSprite.Scale,SpriteEffects.None, 0);
            string wstr = _weight.ToString() + " kg";
            SpriteBatch.DrawString(_fontArial, wstr, _idlePosition + new Vector2(0, _objectSprite.Height*1.25f), Color.White, 0, new Vector2(_fontArial.MeasureString(wstr).X / 2, _fontArial.MeasureString(wstr).Y / 2), 1, SpriteEffects.None, 0);
            SpriteBatch.End();            
            if (_currentState == TurnableObjectState.ROLLING && _angleVeclocity !=0)
            {
                _v.Draw(timer);
                _aht.Draw(timer);
            }
            SpriteBatch.Begin();
            base.Draw(timer);
        }

        public void Pressed(TouchLocation touch)
        {
            Rectangle boundRect = new Rectangle();
            boundRect.X = (int)_position.X - _objectSprite.Width / 2;
            boundRect.Y = (int)_position.Y - _objectSprite.Height / 2;
            boundRect.Width = _objectSprite.Width;
            boundRect.Height = _objectSprite.Height;

            if (touch.Position.X >= boundRect.Left && touch.Position.X <= boundRect.Right
                && touch.Position.Y >= boundRect.Top && touch.Position.Y <= boundRect.Bottom)
            {
                if (_currentState == TurnableObjectState.IDLE || _currentState == TurnableObjectState.ROLLING)
                {
                    _position = touch.Position;
                    _touchID = touch.Id;
                    _currentState = TurnableObjectState.DRAG;
                }
            }

            if (_currentState == TurnableObjectState.ROLLING)
            {
                Rectangle idleRect = new Rectangle();
                idleRect.X = (int)_idlePosition.X - 25;
                idleRect.Y = (int)_idlePosition.Y - 15;
                idleRect.Width = 50;
                idleRect.Height = 30;
                if (touch.Position.X >= idleRect.Left && touch.Position.X <= idleRect.Right
                    && touch.Position.Y >= idleRect.Top && touch.Position.Y <= idleRect.Bottom)
                {
                    
                }
            }
        }

        public bool CheckRemoveEx(TouchLocation touch)
        {
            if (_currentState == TurnableObjectState.ROLLING)
            {
                Rectangle idleRect = new Rectangle();
                idleRect.X = (int)_idlePosition.X - 25;
                idleRect.Y = (int)_idlePosition.Y;
                idleRect.Width = 50;
                idleRect.Height = 50;
                if (touch.Position.X >= idleRect.Left && touch.Position.X <= idleRect.Right
                    && touch.Position.Y >= idleRect.Top && touch.Position.Y <= idleRect.Bottom)
                {
                    return true;
                }
            }
            return false;
        }

        public void Move(TouchLocation touch)
        {
            if (_currentState == TurnableObjectState.DRAG && touch.Id == _touchID)
            {
                _position = touch.Position;
            }
        }

        public bool Release(TouchLocation touch)
        {
            if (touch.Id == _touchID)
            {
                _position.X = touch.Position.X;
                _position.Y = touch.Position.Y;
                return true;
            }
            return false;
        }

        public void SetRollingState()
        {
            _currentState = TurnableObjectState.ROLLING;
        }

        public void SetIdleState()
        {
            _currentState = TurnableObjectState.IDLE;
            _position = _idlePosition;
        }

        public Rectangle getBoundRect()
        {
            Rectangle boundRect = new Rectangle();
            boundRect.X = (int)_position.X - _objectSprite.Width / 2;
            boundRect.Y = (int)_position.Y - _objectSprite.Height / 2;
            boundRect.Width = _objectSprite.Width;
            boundRect.Height = _objectSprite.Height;

            return boundRect;
        }
    }
}
